package com.tgh.gles2.c7.normalMapped;

import com.tgh.gles2.BaseRenderer;
import com.tgh.gles2.R;
import com.tgh.utils.GLFrame;
import com.tgh.utils.GLFrustum;
import com.tgh.utils.GLGeometryTransform;
import com.tgh.utils.GLMatrixStack;
import com.tgh.utils.GLShaderManager;
import com.tgh.utils.GLTools;
import com.tgh.utils.GLTriangleBatch;

import android.content.Context;
import android.opengl.GLES20;
import android.os.SystemClock;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

public class NormalMappedRenderer extends BaseRenderer {

    public NormalMappedRenderer(Context context) {
        super(context);
        sphereBatch=new GLTriangleBatch();
        if (!sphereBatch.loadDataFromSD("sphere_1_52_26")) {
            sphereBatch=GLTools.makeSphere(1.0f, 52, 26);
            sphereBatch.cacheDataToSD("sphere_1_52_26");
        }
        viewFrame=new GLFrame();
        modelViewMatrix=new GLMatrixStack();
        projectionViewMatrix=new GLMatrixStack();
        transformPipleLine=new GLGeometryTransform();
    }

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        initTexture();
        initProgram();
        viewFrame.moveForward(4.0f);
        GLES20.glEnable(GLES20.GL_DEPTH_TEST);
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        GLES20.glViewport(0, 0, width, height);
        viewFrustum=new GLFrustum(35, (float)width/(float)height, 1.0f, 100f);
        projectionViewMatrix.loadMatrix(viewFrustum.getProjectionMatrix());
        transformPipleLine.setMatrixStack(modelViewMatrix, projectionViewMatrix);
    }

    @Override
    public void onDrawFrame(GL10 gl) {
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT|GLES20.GL_DEPTH_BUFFER_BIT);
        
        modelViewMatrix.pushMatrix(viewFrame);
            modelViewMatrix.rotate(-90, 1, 0, 0);
            modelViewMatrix.rotate(SystemClock.elapsedRealtime()/100, 0, 0, 1);
            
            GLES20.glUseProgram(normalMapShader);
            GLES20.glUniform4fv(locDiffuseColor, 1, vDiffuseColor, 0);
            GLES20.glUniform4fv(locAmbientColor, 1, vAmbientColor, 0);
            GLES20.glUniform3fv(locLightPosition, 1, vEyeLight, 0);
            GLES20.glUniformMatrix4fv(locMvMatrix, 1, false, modelViewMatrix.getMatrix().getArray(), 0);
            GLES20.glUniformMatrix4fv(locPMatrix, 1, false, projectionViewMatrix.getMatrix().getArray(), 0);
            GLES20.glUniform1i(locColorMap, 0);
            GLES20.glUniform1i(locNormalMap, 1);
            
            sphereBatch.draw();
        modelViewMatrix.popMatrix();
    }

    @Override
    public void onSurfaceDestroyed() {
        GLES20.glDeleteTextures(2, textures,0);
    }

    private void initProgram() {
        String vpSrc = GLShaderManager.readFileFromAssets(mContext, "NormalMapped.vp");
        String fpSrc = GLShaderManager.readFileFromAssets(mContext, "NormalMapped.fp");
        normalMapShader = GLShaderManager.createProgram(vpSrc, fpSrc,
                new int[]{GLShaderManager.GL_ATTRIBUTE_VERTEX,GLShaderManager.GL_ATTRIBUTE_NORMAL,GLShaderManager.GL_ATTRIBUTE_TEXTURE0}, 
                new String[]{"vVertex","vNormal","vTexture0"}
        );
        locMvMatrix = GLES20.glGetUniformLocation(normalMapShader, "mvMatrix");
        locPMatrix = GLES20.glGetUniformLocation(normalMapShader, "pMatrix");
        locLightPosition = GLES20.glGetUniformLocation(normalMapShader, "vLightPosition");
        locAmbientColor = GLES20.glGetUniformLocation(normalMapShader, "ambientColor");
        locDiffuseColor = GLES20.glGetUniformLocation(normalMapShader, "diffuseColor");
        locColorMap = GLES20.glGetUniformLocation(normalMapShader, "colorMap");
        locNormalMap = GLES20.glGetUniformLocation(normalMapShader, "normalMap");
    }

    private void initTexture() {
        textures = GLTools.genTextures(2);
        GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]);
        GLTools.loadDrawableToTexture2D(
                mContext, R.drawable.ice_moon, 
                GLES20.GL_LINEAR_MIPMAP_LINEAR, GLES20.GL_LINEAR,
                GLES20.GL_CLAMP_TO_EDGE,true);
        
        GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[1]);
        GLTools.loadDrawableToTexture2D(
                mContext, R.drawable.ice_moon_bump, 
                GLES20.GL_LINEAR_MIPMAP_LINEAR, GLES20.GL_LINEAR,
                GLES20.GL_REPEAT,true);
    }
    
    private GLFrame viewFrame;
    private GLFrustum viewFrustum;
    private GLTriangleBatch sphereBatch;
    private GLMatrixStack modelViewMatrix;
    private GLMatrixStack projectionViewMatrix;
    private GLGeometryTransform transformPipleLine;
    private int normalMapShader;
    private int locMvMatrix;
    private int locPMatrix;
    private int locLightPosition;
    private int locAmbientColor;
    private int locDiffuseColor;
    private int locColorMap;
    private int locNormalMap;
    private int[] textures;
    private float[] vEyeLight={-100,100,150};
    private float[] vAmbientColor={0.2f,0.2f,0.2f,1.0f};
    private float[] vDiffuseColor={1.0f,1.0f,1.0f,1.0f};
    
}
